package com.xzy.learn.spring.bean.initialization;

import com.xzy.learn.spring.bean.initialization.bean.StudentC;
import com.xzy.learn.spring.bean.initialization.config.LazyInitializationConfig;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 延迟初始化
 *
 * @author xzy.xiao
 * @date 2022/6/2  9:41
 */
public class LazyInitializationBeanDemo {

    public static void main(String[] args) {
//        setLazyInitByTag();
//        setLazyInitByAnnotation();
//        setLazyInitByDefinition();
        testTheDifferenceBetweenLazyBeanAndNoLazyBean();
    }

    /**
     * 设置延迟初始化的方式：
     * 1) <bean lazy-init="true"/>
     * 2) @Lazy
     * 3) BeanDefinition
     */
    public static void setLazyInitByTag() {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/bean-lazy-initialization.xml");

        StudentC bean = classPathXmlApplicationContext.getBean(StudentC.class);
        System.out.println(bean);

        classPathXmlApplicationContext.close();
    }

    public static void setLazyInitByAnnotation() {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(LazyInitializationConfig.class);

        StudentC bean = annotationConfigApplicationContext.getBean(StudentC.class);
        System.out.println(bean);

        annotationConfigApplicationContext.close();

    }

    public static void setLazyInitByDefinition() {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(StudentC.class);
        beanDefinitionBuilder.setInitMethodName("myInitMethod");
        beanDefinitionBuilder.setLazyInit(true);

        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
        annotationConfigApplicationContext.registerBeanDefinition("studentC", beanDefinitionBuilder.getBeanDefinition());
        annotationConfigApplicationContext.refresh();

        StudentC bean = annotationConfigApplicationContext.getBean(StudentC.class);
        System.out.println(bean);

        annotationConfigApplicationContext.close();
    }

    public static void testTheDifferenceBetweenLazyBeanAndNoLazyBean() {
        System.out.println("创建容器...");
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/bean-lazy-initialization.xml");

        System.out.println("获取 No-Lazy-Bean：");
        StudentC noLazyBean = classPathXmlApplicationContext.getBean("no-lazy-bean", StudentC.class);
        System.out.println(noLazyBean);

        System.out.println("获取 Lazy-Bean：");
        StudentC lazyBean = classPathXmlApplicationContext.getBean("lazy-bean", StudentC.class);
        System.out.println(lazyBean);

        classPathXmlApplicationContext.close();
    }
}
